package com.ev.hr.service.impl;

import com.ev.apis.model.DsResultResponse;
import com.ev.framework.il8n.MessageSourceHandler;
import com.ev.framework.utils.PinYinUtil;
import com.ev.framework.utils.R;
import com.ev.framework.utils.RepeatUtil;
import com.ev.framework.utils.StringUtils;
import com.ev.hr.dao.SalaryAccountingDao;
import com.ev.hr.dao.SalaryFormulaChildDao;
import com.ev.hr.dao.SalaryProjectDao;
import com.ev.hr.domain.SalaryFormulaChildDO;
import com.ev.hr.domain.SalaryProjectDO;
import com.ev.hr.service.SalaryProjectService;
import com.ev.hr.vo.SalaryAccountingPageParam;
import com.ev.hr.vo.SalaryProjectPageParam;
import com.ev.hr.vo.SalaryProjectParam;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class SalaryProjectServiceImpl implements SalaryProjectService {
	@Autowired
	private SalaryProjectDao salaryProjectDao;
	@Autowired
	private SalaryAccountingDao salaryAccountingDao;
	@Autowired
	private SalaryFormulaChildDao salaryFormulaChildDao;
	@Autowired
	private MessageSourceHandler messageSourceHandler;

	@Override
	public SalaryProjectDO get(Long id){
		return salaryProjectDao.get(id);
	}

	@Override
	public List<SalaryProjectDO> list(Map<String, Object> map){
		return salaryProjectDao.list(map);
	}

	@Override
	public int count(Map<String, Object> map){
		return salaryProjectDao.count(map);
	}

	@Override
	public int save(SalaryProjectDO salaryProject){
		return salaryProjectDao.save(salaryProject);
	}

	@Override
	public int update(SalaryProjectDO salaryProject){
		return salaryProjectDao.update(salaryProject);
	}

	@Override
	public int updateAll(SalaryProjectDO salaryProject){
		return salaryProjectDao.updateAll(salaryProject);
	}

	@Override
	public int remove(Long id){
		return salaryProjectDao.remove(id);
	}

	@Override
	public int batchRemove(Long[] ids){
		return salaryProjectDao.batchRemove(ids);
	}

	@Override
	public Map<String, Object> pageList(SalaryProjectPageParam pageParam) {
		Map<String,Object> result = Maps.newHashMap();
		pageParam.setSalaryItemName(StringUtils.sqlLike(pageParam.getSalaryItemName()));
		List<Map<String, Object>> data = salaryProjectDao.pageList(pageParam);
		int total = salaryProjectDao.pageCount(pageParam);
		result.put("data", new DsResultResponse(pageParam.getPageno(),pageParam.getPagesize(),total,data));
		return R.ok(result);
	}

	@Override
	public Map<String, Object> getById(Long id) {
		Map<String, Object> detail = this.salaryProjectDao.getById(id);
		if (detail != null) {
			Map<String,Object> result = Maps.newHashMap();
			result.put("data",detail);
			return R.ok(result);
		}
		return R.error();
	}

	@Override
	public R delete(Long[] ids) {
		for (Long id : ids) {
			SalaryProjectDO salaryProjectDO = this.get(id);
			if (salaryProjectDO == null) {
				return R.error();
			}
			if(salaryProjectDO.getIsUpdate()==0){
				return R.error(messageSourceHandler.getMessage("hr.salary.project.operate",null));
			}
		}

		Map<String,Object> param = Maps.newHashMap();
		List<Long> projectIdList = Arrays.asList(ids);
		param.put("projectIdList",projectIdList);
		List<SalaryFormulaChildDO> formulaList = salaryFormulaChildDao.list(param);
		if (formulaList.size() > 0) {
			return R.error(messageSourceHandler.getMessage("hr.salary.project.isUse",null));
		}

		this.batchRemove(ids);
		return R.ok();
	}

	@Override
	public R saveAndVerify(SalaryProjectDO saveParam) {
		// 验重
		boolean checkRepeat = this.checkRepeat(saveParam);
		if(checkRepeat){
			return R.error(messageSourceHandler.getMessage("hr.duplicate.sortNoOrName",null));
		}
		Long id = saveParam.getId();
		if(saveParam.getId()!=null){
			SalaryProjectDO salaryProjectDO = this.get(saveParam.getId());
			if(salaryProjectDO.getIsUpdate()==0){
				return R.error(messageSourceHandler.getMessage("hr.salary.project.operate",null));
			}
			salaryProjectDao.update(saveParam);
		}else {
			String value = PinYinUtil.getPinYinHasLine(saveParam.getSalaryItemName());
			Map<String,Object> param = Maps.newHashMap();
			param.put("value",value);
			int count = this.count(param);
			if(count>0){
				// 若已存在该value值 则时value_主键 形式保存
				salaryProjectDao.save(saveParam);
				id = saveParam.getId();
				value += "_"+id;
				saveParam.setValue(value);
				this.update(saveParam);
			}else {
				saveParam.setValue(value);
				salaryProjectDao.save(saveParam);
				id = saveParam.getId();
			}
		}
		Map<String,Object> result = Maps.newHashMap();
		result.put("id",id);
		return R.ok(result);
	}

	private boolean checkRepeat(SalaryProjectDO saveParam) {
		Map<String,Object> map = Maps.newHashMap();
		Long id = saveParam.getId();
		String salaryItemName = saveParam.getSalaryItemName();
        map.put("offset", 0);
        map.put("limit", 2);
		map.put("salaryItemName",salaryItemName);

		List<SalaryProjectDO> list = this.list(map);
		return RepeatUtil.checkRepeatColumn(list,id);
	}

	@Override
	public Map<String, Object> getProjectList(SalaryProjectParam salaryProjectParam) {
		Map<String,Object> result = Maps.newHashMap();
		List<Map<String, Object>> projectList = salaryProjectDao.getProjectList(salaryProjectParam);

		// 公式内的项目
		if(salaryProjectParam.getMonthDate()!=null){
			SalaryAccountingPageParam salaryAccountingPageParam = new SalaryAccountingPageParam();
			String month = salaryProjectParam.getMonthDate().substring(0, 7);
			salaryAccountingPageParam.setMonthDate(month);
			List<Map<String, Object>> data = salaryAccountingDao.pageList(salaryAccountingPageParam);
			if(data.size()>0 && data.get(0).get("formulaId")!=null){
				Object formulaId = data.get(0).get("formulaId");
				Map<String,Object> param = Maps.newHashMap();
				param.put("mainId",formulaId);
				List<SalaryFormulaChildDO> formulaList = salaryFormulaChildDao.list(param);
				List<Long> formulaLProjectId = formulaList
						.stream()
						.map(SalaryFormulaChildDO::getProjectId)
						.collect(Collectors.toList());
				List<Long> id = projectList
						.stream()
						.map(e -> Long.parseLong(e.get("id").toString()))
						.collect(Collectors.toList());
				formulaLProjectId.removeAll(id);
				if(formulaLProjectId.size()>0){
					SalaryProjectParam salaryProject = new SalaryProjectParam();
					salaryProject.setIdList(formulaLProjectId);
					List<Map<String, Object>> newProjectList = salaryProjectDao.getProjectList(salaryProject);
					projectList.addAll(newProjectList);
				}
			}
		}
		if (projectList.size() > 0) {
			projectList.sort(Comparator.comparing(e->Integer.parseInt(e.get("sortNo").toString())));
			result.put("data",projectList);
		}
		return result;
	}

}
